package com.herui.sdyu_lib.base.fragment;

import android.os.Handler;


import com.herui.sdyu_lib.base.BaseFragment;
import com.herui.sdyu_lib.base.FragmentDirectionAnim;
import com.herui.sdyu_lib.utils.LogUtils;

import java.util.List;

import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;


/**
 * Created by Administrator on 2016/5/14.
 */
public class Fragmentation {

    private FragmentManager mFragmentManager;
    private int constantID;

    private Handler mHandler;

    public Fragmentation(FragmentManager mFragmentManager) {
        this.mFragmentManager = mFragmentManager;
        mHandler = new Handler();
    }

    public Fragmentation(FragmentManager mFragmentManager, int constantID) {
        this.mFragmentManager = mFragmentManager;
        this.constantID = constantID;

        mHandler = new Handler();
    }

    /**
     * replace
     *
     * @param to
     * @param saveBack 是否保留到栈
     */
    public void replace(Fragment to, boolean saveBack, FragmentDirectionAnim anim) {
        if (to.isVisible())
            return;
        // 开启Fragment事务
        FragmentTransaction ft = mFragmentManager.beginTransaction();
        String toName = to.getClass().getName();
        if (anim != null)
            ft.setCustomAnimations(anim.enterAnim, anim.exitAnim);
        else
            ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
        ft.replace(constantID, to, toName);
        if (saveBack)
            ft.addToBackStack(toName);
        ft.commit();
    }

    /**
     * 添加fragment 隐藏老的fragment 保留栈
     *
     * @param from
     * @param to
     */
    public void switchBrotherFragment(BaseFragment from, BaseFragment to, FragmentDirectionAnim
            anim) {

        if (to.isVisible())
            return;
        FragmentTransaction ft = mFragmentManager.beginTransaction();
        if (anim != null)
            ft.setCustomAnimations(anim.enterAnim, anim.exitAnim);
        else
            ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);

        if (from != null)
            ft.hide(from);
        if (!to.isAdded()) {
            ft.add(constantID, to, to.TAG).commit();
        } else {
            ft.show(to).commit();
        }
    }

    /**
     * 添加 隐藏之前fragment
     *
     * @param from
     * @param to
     */
    public void add(BaseFragment from, BaseFragment to, FragmentDirectionAnim anim) {
        String toName = to.getClass().getName();
        FragmentTransaction ft = mFragmentManager.beginTransaction();
        if (anim != null)
            ft.setCustomAnimations(anim.enterAnim, anim.exitAnim, anim.popEnter, anim.popExit);
        else
            ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
        ft.add(constantID, to, toName);

        if (from != null) {
            ft.hide(from);
        }
        ft.addToBackStack(toName);
        ft.commit();
    }

    /**
     * 添加移除之前的fragment
     *
     * @param from
     * @param to
     */
    public void addWithFinish(BaseFragment from, BaseFragment to, FragmentDirectionAnim anim) {

        Fragment preFragment = getPreFragment(from);

        mFragmentManager.beginTransaction().remove(from).commit();
        mFragmentManager.popBackStackImmediate();

        String toName = to.getClass().getName();
        FragmentTransaction ft = mFragmentManager.beginTransaction();
        if (anim != null)
            ft.setCustomAnimations(anim.enterAnim, anim.exitAnim);
        else
            ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
        ft.add(constantID, to, toName)
                .addToBackStack(toName);

        if (preFragment != null) {
            LogUtils.i("preFragment :" + preFragment.getClass());
            ft.hide(preFragment);
        }
        ft.commit();
    }

    /**
     * 删除某个frament 需要先remove 然后再从栈中将其移除
     *
     * @param fragment
     */
    public void remove(Fragment fragment) {
        mFragmentManager.beginTransaction().remove(fragment).commit();
        mFragmentManager.popBackStack();
    }

    /**
     * @param fragment
     * @return
     */
    private Fragment getPreFragment(Fragment fragment) {
        List<Fragment> fragmentList = mFragmentManager.getFragments();
        Fragment preFragment = null;
        if (fragmentList != null) {
            int index = fragmentList.indexOf(fragment);
            for (int i = index - 1; i >= 0; i--) {
                preFragment = fragmentList.get(i);
                if (preFragment != null) {
                    break;
                }
            }
        }
        return preFragment;
    }

    /**
     * 出栈到目标fragment
     *
     * @param fragmentClass 目标fragment
     * @param includeSelf   是否包含该fragment
     */
    public void popTo(Class<?> fragmentClass, boolean includeSelf, FragmentManager
            fragmentManager) {
        try {
            Fragment rootFragment = fragmentManager.findFragmentByTag(fragmentClass.getName());
            if (includeSelf) {
                rootFragment = getPreFragment(rootFragment);
            }
            BaseFragment fromFragment = getTopFragment(fragmentManager);

            if (rootFragment == fromFragment) {
                return;
            }

            // 这里为什么要这么做
            fragmentManager.beginTransaction().remove(fromFragment).commit();

            int flag = includeSelf ? FragmentManager.POP_BACK_STACK_INCLUSIVE : 0;
            // 解决pop多个fragment的bug
            popBackFix(fragmentClass, flag, fragmentManager);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 解决pop多个fragment异常问题
     *
     * @param fragmentClass
     * @param flag
     */
    private void popBackFix(Class<?> fragmentClass, int flag, final FragmentManager
            fragmentManager) {
//        mActivity.preparePopMultiple();
        fragmentManager.popBackStackImmediate(fragmentClass.getName(), flag);
//        mActivity.popFinish();

//        mHandler.post(new Runnable() {
//            @Override
//            public void run() {
//                FragmentTransactionBugFixHack.reorderIndices(fragmentManager);
//            }
//        });
    }

    @SuppressWarnings("unchecked")
    public <T extends BaseFragment> T findStackFragment(Class<T> fragmentClass, FragmentManager
            fragmentManager) {
        Fragment fragment = fragmentManager.findFragmentByTag(fragmentClass.getName());
        if (fragment == null) {
            return null;
        }
        return (T) fragment;
    }

    /**
     * 获得栈顶Fragment
     *
     * @return
     */
    public BaseFragment getTopFragment(FragmentManager fragmentManager) {
        int count = fragmentManager.getBackStackEntryCount();
        if (count > 0) {
            String tag = fragmentManager.getBackStackEntryAt(count - 1).getName();

//            LogUtils.i("getBackStackEntryAt:" + tag);
            Fragment fragment = fragmentManager.findFragmentByTag(tag);
            if (fragment != null) {
                if (fragment instanceof BaseFragment) {
                    return (BaseFragment) fragment;
                } else {
                    throw new RuntimeException("The top Fragment is not a SupportFragment!");
                }
            }
        }
//        List<Fragment> fragments = fragmentManager.getFragments();
//        if (fragments != null) {
//            for (int i = fragments.size() - 1; i >= 0; i--)
//                if (fragments.get(i) != null)
//                    return (BaseFragment) fragments.get(i);
//        }
        return null;
    }


    public void back(FragmentManager fragmentManager) {
        int count = fragmentManager.getBackStackEntryCount();

        if (count > 0) {
            fragmentManager.popBackStackImmediate();
        }
    }

}
